package com.nanhai.buddhist.college.framework.mybatis.config;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;

import com.github.yulichang.injector.MPJSqlInjector;
import com.github.yulichang.interceptor.MPJInterceptor;
import com.nanhai.buddhist.college.framework.mybatis.core.handler.CustomerIdGenerator;
import com.nanhai.buddhist.college.framework.mybatis.core.handler.DefaultDBFieldHandler;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
import com.baomidou.mybatisplus.extension.incrementer.H2KeyGenerator;
import com.baomidou.mybatisplus.extension.incrementer.KingbaseKeyGenerator;
import com.baomidou.mybatisplus.extension.incrementer.OracleKeyGenerator;
import com.baomidou.mybatisplus.extension.incrementer.PostgreKeyGenerator;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;

import javax.sql.DataSource;

/**
 * MyBaits 配置类
 *
 * @author 开发
 */
@Configuration
@MapperScan(value = "${college.info.base-package}", annotationClass = Mapper.class,
        lazyInitialization = "${mybatis.lazy-initialization:false}") // Mapper 懒加载，目前仅用于单元测试
public class CollegeMybatisAutoConfiguration {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();

        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); // 分页插件
        return mybatisPlusInterceptor;
    }


    @Bean
    public GlobalConfig globalConfig(MPJSqlInjector mpjSqlInjector) {
        GlobalConfig conf = new GlobalConfig();
        conf.setIdentifierGenerator(new CustomerIdGenerator());
        conf.setMetaObjectHandler(new DefaultDBFieldHandler());
        conf.setSqlInjector(mpjSqlInjector);
        return conf;
    }

//    @Bean
//    public GlobalConfig globalConfig(MPJSqlInjector mpjSqlInjector) {
//        GlobalConfig config = new GlobalConfig();
//        config.setSqlInjector(mpjSqlInjector);
//        return config;
//    }

    /**
     * 关联SqlSessionFactory与GlobalConfig
     * 设置mybatis 拦截器
     * 其他配置 略
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource, GlobalConfig globalConfig,
                                               MybatisPlusInterceptor mybatisPlusInterceptor, MPJInterceptor mpjInterceptor) throws Exception {
        MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        //关联SqlSessionFactory与GlobalConfig
        sessionFactory.setGlobalConfig(globalConfig);
        //设置mybatis 拦截器 (注意顺序 mpjInterceptor要在最后)
        sessionFactory.setPlugins(mybatisPlusInterceptor,mpjInterceptor);
        //其他配置 略
        return sessionFactory.getObject();
    }



//    @Bean
//    public MetaObjectHandler defaultMetaObjectHandler(){
//        return new DefaultDBFieldHandler(); // 自动填充参数类
//    }

    @Bean
    @ConditionalOnProperty(prefix = "mybatis-plus.global-config.db-config", name = "id-type", havingValue = "INPUT")
    public IKeyGenerator keyGenerator(ConfigurableEnvironment environment) {
        DbType dbType = IdTypeEnvironmentPostProcessor.getDbType(environment);
        if (dbType != null) {
            switch (dbType) {
                case POSTGRE_SQL:
                    return new PostgreKeyGenerator();
                case ORACLE:
                case ORACLE_12C:
                    return new OracleKeyGenerator();
                case H2:
                    return new H2KeyGenerator();
                case KINGBASE_ES:
                    return new KingbaseKeyGenerator();
            }
        }
        // 找不到合适的 IKeyGenerator 实现类
        throw new IllegalArgumentException(StrUtil.format("DbType{} 找不到合适的 IKeyGenerator 实现类", dbType));
    }

}
